home *** CD-ROM | disk | FTP | other *** search
/ The Games Machine 80 / XENIATGM80.iso / Goodies / Blood 2 / Source / data.z / MenuCharacter.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-04-02  |  25.4 KB  |  851 lines

  1. //*************************************************************************
  2. //*************************************************************************
  3. //***** MODULE  : MenuCharacter.cpp
  4. //***** PURPOSE : Blood 2 Character Creation Screen
  5. //***** CREATED : 10/11/98
  6. //*************************************************************************
  7. //*************************************************************************
  8.  
  9. #include "MenuBase.h"
  10. #include "MenuCharacter.h"
  11. #include "MainMenus.h"
  12. #include "MenuCommands.h"
  13. #include "BloodClientShell.h"
  14. #include "WeaponDefs.h"
  15. #include "VKDefs.h"
  16. #include <direct.h>
  17. #include <stdio.h>
  18. #include <io.h>
  19.  
  20. //*************************************************************************
  21.  
  22. CharacterMenuInfo g_CharacterMenuInfo[MAX_CHARACTER_INFO] =
  23. {
  24.     { "caleb_single.pcx", CHARACTER_CALEB, MULTIPLAY_SKIN_NORMAL, },
  25.     { "caleb_red.pcx", CHARACTER_CALEB, MULTIPLAY_SKIN_RED, },
  26.     { "caleb_blue.pcx", CHARACTER_CALEB, MULTIPLAY_SKIN_BLUE, },
  27.     { "caleb_green.pcx", CHARACTER_CALEB, MULTIPLAY_SKIN_GREEN, },
  28.     { "caleb_yellow.pcx", CHARACTER_CALEB, MULTIPLAY_SKIN_YELLOW, },
  29.     { "ophelia_single.pcx", CHARACTER_OPHELIA, MULTIPLAY_SKIN_NORMAL, },
  30.     { "ophelia_red.pcx", CHARACTER_OPHELIA, MULTIPLAY_SKIN_RED, },
  31.     { "ophelia_blue.pcx", CHARACTER_OPHELIA, MULTIPLAY_SKIN_BLUE, },
  32.     { "ophelia_green.pcx", CHARACTER_OPHELIA, MULTIPLAY_SKIN_GREEN, },
  33.     { "ophelia_yellow.pcx", CHARACTER_OPHELIA, MULTIPLAY_SKIN_YELLOW, },
  34.     { "ishmael_single.pcx", CHARACTER_ISHMAEL, MULTIPLAY_SKIN_NORMAL, },
  35.     { "ishmael_red.pcx", CHARACTER_ISHMAEL, MULTIPLAY_SKIN_RED, },
  36.     { "ishmael_blue.pcx", CHARACTER_ISHMAEL, MULTIPLAY_SKIN_BLUE, },
  37.     { "ishmael_green.pcx", CHARACTER_ISHMAEL, MULTIPLAY_SKIN_GREEN, },
  38.     { "ishmael_yellow.pcx", CHARACTER_ISHMAEL, MULTIPLAY_SKIN_YELLOW, },
  39.     { "gabby_single.pcx", CHARACTER_GABREILLA, MULTIPLAY_SKIN_NORMAL, },
  40.     { "gabby_red.pcx", CHARACTER_GABREILLA, MULTIPLAY_SKIN_RED, },
  41.     { "gabby_blue.pcx", CHARACTER_GABREILLA, MULTIPLAY_SKIN_BLUE, },
  42.     { "gabby_green.pcx", CHARACTER_GABREILLA, MULTIPLAY_SKIN_GREEN, },
  43.     { "gabby_yellow.pcx", CHARACTER_GABREILLA, MULTIPLAY_SKIN_YELLOW, },
  44.  
  45. #ifdef _ADDON
  46.     { "interface_AO\\m_cultist1.pcx", CHARACTER_M_CULTIST, MULTIPLAY_SKIN_NORMAL, },
  47.     { "interface_AO\\clown2.pcx", CHARACTER_M_CULTIST, MULTIPLAY_SKIN_RED, },
  48.     { "interface_AO\\clown1.pcx", CHARACTER_M_CULTIST, MULTIPLAY_SKIN_BLUE, },
  49.     { "interface_AO\\clown3.pcx", CHARACTER_M_CULTIST, MULTIPLAY_SKIN_GREEN, },
  50.     { "interface_AO\\m_cultist3.pcx", CHARACTER_M_CULTIST, MULTIPLAY_SKIN_YELLOW, },
  51.     { "interface_AO\\f_cultist1.pcx", CHARACTER_F_CULTIST, MULTIPLAY_SKIN_NORMAL, },
  52.     { "interface_AO\\souldrudge1.pcx", CHARACTER_SOULDRUDGE, MULTIPLAY_SKIN_NORMAL, },
  53.     { "interface_AO\\prophet.pcx", CHARACTER_PROPHET, MULTIPLAY_SKIN_NORMAL, },
  54. #endif
  55.  
  56. };
  57.  
  58. //*************************************************************************
  59.  
  60. CMenuCharacter::CMenuCharacter()
  61. {
  62.     m_szBackground = "interface\\charscreen\\charbackground.pcx";
  63.     m_bBoxFormat = DFALSE;
  64.  
  65.     m_hCharacterPic = DNULL;
  66.  
  67.     m_PlayerIndex = 0;
  68.     m_ExtraPoints = 4;
  69.  
  70.     m_Player.dwCharacter = g_CharacterMenuInfo[m_PlayerIndex].nCharacter;
  71.     m_Player.dwColor = g_CharacterMenuInfo[m_PlayerIndex].nColor;
  72.     m_Player.dwStrength = DEFAULT_ATTRIBUTE - 1;
  73.     m_Player.dwSpeed = DEFAULT_ATTRIBUTE - 1;
  74.     m_Player.dwResist = DEFAULT_ATTRIBUTE - 1;
  75.     m_Player.dwFocus = DEFAULT_ATTRIBUTE - 1;
  76.     m_Player.dwWeap1 = WEAP_NONE;
  77.     m_Player.dwWeap2 = WEAP_NONE;
  78.     m_Player.dwWeap3 = WEAP_NONE;
  79.     m_Player.dwWeap4 = WEAP_NONE;
  80.     m_Player.dwWeap5 = WEAP_NONE;
  81.     m_Player.dwWeap6 = WEAP_NONE;
  82.     m_Player.dwWeap7 = WEAP_NONE;
  83.     m_Player.dwWeap8 = WEAP_NONE;
  84.     m_Player.dwWeap9 = WEAP_NONE;
  85.  
  86.     m_hRightArrow = DNULL;
  87.  
  88.     m_hStats[0] = DNULL;
  89.     m_hStats[1] = DNULL;
  90.     m_hStats[2] = DNULL;
  91.     m_hStats[3] = DNULL;
  92.  
  93.     m_hExtraCtrl = DNULL;
  94.     m_hExtraNumCtrl = DNULL;
  95.  
  96.     m_hWeaponsCtrl = DNULL;
  97.  
  98.     for(int i = 0; i < 10; i++)
  99.     {
  100.         m_hWeaponNums[i] = DNULL;
  101.         m_hWeapons[i] = DNULL;
  102.     }
  103.  
  104.     m_bSwitchResolutions=DFALSE;
  105.     m_bGoingToFilesMenu=DFALSE;
  106.  
  107.     m_nOldScreenWidth=640;
  108.     m_nOldScreenHeight=480;
  109. }
  110.  
  111. //*************************************************************************
  112.  
  113. CMenuCharacter::~CMenuCharacter()
  114. {
  115.     if(m_hRightArrow)    delete m_hRightArrow;
  116.     if(m_hExtraCtrl)    delete m_hExtraCtrl;
  117.     if(m_hWeaponsCtrl)    delete m_hWeaponsCtrl;
  118.  
  119.     if(m_hExtraNumCtrl)    delete m_hExtraNumCtrl;
  120.  
  121.     for(int i = 0; i < 4; i++)
  122.         if(m_hStats[i])        delete m_hStats[i];
  123.  
  124.     for(i = 0; i < 10; i++)
  125.     {
  126.         if(m_hWeaponNums[i])    delete m_hWeaponNums[i];
  127.         if(m_hWeapons[i])        delete m_hWeapons[i];
  128.     }
  129. }
  130.  
  131. //*************************************************************************
  132.  
  133. void CMenuCharacter::Build()
  134. {
  135.     CMenuBase::Build();
  136.  
  137.     AddFadeItemOption("interface\\charscreen\\arrows\\leftarrow_", 6, "LEFT ARROW", 0, 60, 380);
  138.  
  139.     AddFadeItemOption("interface\\charscreen\\titles\\strength_", 6, "STRENGTH", 0, 206, 130);
  140.     AddFadeItemOption("interface\\charscreen\\titles\\resistance_", 6, "RESISTANCE", 0, 204, 172);
  141.     AddFadeItemOption("interface\\charscreen\\titles\\speed_", 6, "SPEED", 0, 206, 214);
  142.     AddFadeItemOption("interface\\charscreen\\titles\\focus_", 6, "FOCUS", 0, 206, 256);
  143.  
  144.     AddFadeItemOption("interface\\charscreen\\fields\\weapon2_", 6, "WEAPON2", 0, 380, 134);
  145.     AddFadeItemOption("interface\\charscreen\\fields\\weapon3_", 6, "WEAPON3", 0, 380, 158);
  146.     AddFadeItemOption("interface\\charscreen\\fields\\weapon4_", 6, "WEAPON4", 0, 380, 181);
  147.     AddFadeItemOption("interface\\charscreen\\fields\\weapon5_", 6, "WEAPON5", 0, 380, 204);
  148.     AddFadeItemOption("interface\\charscreen\\fields\\weapon6_", 6, "WEAPON6", 0, 380, 226);
  149.     AddFadeItemOption("interface\\charscreen\\fields\\weapon7_", 6, "WEAPON7", 0, 380, 249);
  150.     AddFadeItemOption("interface\\charscreen\\fields\\weapon8_", 6, "WEAPON8", 0, 380, 272);
  151.     AddFadeItemOption("interface\\charscreen\\fields\\weapon9_", 6, "WEAPON9", 0, 380, 295);
  152.     AddFadeItemOption("interface\\charscreen\\fields\\weapon10_", 6, "WEAPON10", 0, 380, 319);
  153.  
  154.     AddFadeItemOption("interface\\charscreen\\titles\\save_", 6, "SAVE", MENU_CMD_SAVE_CHARACTER, 517, 356);
  155.     AddFadeItemOption("interface\\charscreen\\titles\\load_", 6, "LOAD", MENU_CMD_LOAD_CHARACTER, 509, 382);
  156.     AddFadeItemOption("interface\\charscreen\\titles\\delete_", 6, "DELETE", MENU_CMD_DELETE_CHARACTER, 499, 407);
  157.  
  158.     BuildExtraCtrls();
  159.  
  160.     ChangeCharacterPic(0);
  161.  
  162.     m_hTransColor = m_pClientDE->SetupColor1(1.0f, 0.0f, 1.0f, DFALSE);
  163. }
  164.  
  165. //*************************************************************************
  166.  
  167. void CMenuCharacter::BuildExtraCtrls()
  168. {
  169.     m_hRightArrow = InitFadeItemCtrl("interface\\charscreen\\arrows\\rightarrow_", 6, "RIGHT ARROW", 0, 188, 377);
  170.     m_hExtraCtrl = InitFadeItemCtrl("interface\\charscreen\\titles\\extrapts_", 6, "EXTRA POINTS", 0, 206, 295);
  171.     m_hWeaponsCtrl = InitFadeItemCtrl("interface\\charscreen\\titles\\weapons_", 6, "WEAPONS", 0, 491, 95);
  172.  
  173.     m_hExtraNumCtrl = InitNumberCtrl(0, 8, m_ExtraPoints, 0, 330, 313);
  174.  
  175.     m_hStats[0] = InitNumberCtrl(0, 5, m_Player.dwStrength, 0, 330, 145);
  176.     m_hStats[1] = InitNumberCtrl(0, 5, m_Player.dwResist, 0, 330, 187);
  177.     m_hStats[2] = InitNumberCtrl(0, 5, m_Player.dwSpeed, 0, 330, 229);
  178.     m_hStats[3] = InitNumberCtrl(0, 5, m_Player.dwFocus, 0, 330, 271);
  179.  
  180.     m_hWeapons[0] = InitWeaponCtrl(WEAP_MELEE, 0, 410, 116, DFALSE);
  181.     m_hWeapons[1] = InitWeaponCtrl(0, 0, 410, 139, DTRUE);
  182.     m_hWeapons[2] = InitWeaponCtrl(0, 0, 410, 162, DTRUE);
  183.     m_hWeapons[3] = InitWeaponCtrl(0, 0, 410, 185, DTRUE);
  184.     m_hWeapons[4] = InitWeaponCtrl(0, 0, 410, 208, DTRUE);
  185.     m_hWeapons[5] = InitWeaponCtrl(0, 0, 410, 231, DTRUE);
  186.     m_hWeapons[6] = InitWeaponCtrl(0, 0, 410, 254, DTRUE);
  187.     m_hWeapons[7] = InitWeaponCtrl(0, 0, 410, 277, DTRUE);
  188.     m_hWeapons[8] = InitWeaponCtrl(0, 0, 410, 300, DTRUE);
  189.     m_hWeapons[9] = InitWeaponCtrl(0, 0, 410, 323, DTRUE);
  190.  
  191.     m_hWeaponNums[0] = InitWeaponNumCtrl(WEAP_MELEE, 0, 390, 116, DFALSE);
  192.     m_hWeaponNums[1] = InitWeaponNumCtrl(0, 0, 390, 139, DTRUE);
  193.     m_hWeaponNums[2] = InitWeaponNumCtrl(0, 0, 390, 162, DTRUE);
  194.     m_hWeaponNums[3] = InitWeaponNumCtrl(0, 0, 390, 185, DTRUE);
  195.     m_hWeaponNums[4] = InitWeaponNumCtrl(0, 0, 390, 208, DTRUE);
  196.     m_hWeaponNums[5] = InitWeaponNumCtrl(0, 0, 390, 231, DTRUE);
  197.     m_hWeaponNums[6] = InitWeaponNumCtrl(0, 0, 390, 254, DTRUE);
  198.     m_hWeaponNums[7] = InitWeaponNumCtrl(0, 0, 390, 277, DTRUE);
  199.     m_hWeaponNums[8] = InitWeaponNumCtrl(0, 0, 390, 300, DTRUE);
  200.     m_hWeaponNums[9] = InitWeaponNumCtrl(0, 0, 390, 323, DTRUE);
  201. }
  202.  
  203. //*************************************************************************
  204.  
  205. CLTGUIFadeItemCtrl* CMenuCharacter::InitFadeItemCtrl(char *lpszOptionSurfPrefix, int nSurfaces, char *lpszOptionText, DWORD dwCommandID, int x, int y)
  206. {
  207.     char szTempString[256];
  208.  
  209.     assert(nSurfaces > 0);
  210.  
  211.     HSURFACE *pSurfArray=new HSURFACE[nSurfaces];
  212.  
  213.     // Load the option surfaces
  214.     int i;
  215.     for ( i=0; i < nSurfaces; i++ )
  216.     {        
  217.         // Add the extra zero if we are under 10 (index < 9)
  218.         if ( i+1 < 10 )
  219.             sprintf(szTempString, "%s0%d.pcx", lpszOptionSurfPrefix, i+1);
  220.         else
  221.             sprintf(szTempString, "%s%d.pcx", lpszOptionSurfPrefix, i+1);
  222.  
  223.         pSurfArray[i]=m_pClientDE->CreateSurfaceFromBitmap(szTempString);
  224.     }
  225.  
  226.     // Load the disabled surface
  227.     sprintf(szTempString, "%sdis.pcx", lpszOptionSurfPrefix);
  228.     HSURFACE hDisabledSurf=m_pClientDE->CreateSurfaceFromBitmap(szTempString);
  229.  
  230.     // Create the new menu option
  231.     CLTGUIFadeItemCtrl *pOption=new CLTGUIFadeItemCtrl;
  232.     if ( !pOption->Create(m_pClientDE, dwCommandID, pSurfArray, nSurfaces, hDisabledSurf, TRUE, DNULL) )
  233.     {
  234.         delete []pSurfArray;
  235.         delete pOption;
  236.  
  237.         return DNULL;
  238.     }
  239.  
  240.     pOption->SetPos(x, y);
  241.  
  242.     delete []pSurfArray;
  243.  
  244.     return pOption;
  245. }
  246.  
  247. //*************************************************************************
  248.  
  249. CLTGUITextItemCtrl* CMenuCharacter::InitNumberCtrl(int low, int high, int index, DWORD dwCommandID, int x, int y)
  250. {
  251.     char    str[5];
  252.  
  253.     itoa(low, str, 10);
  254.  
  255.     HSTRING hString=m_pClientDE->CreateString(str);
  256.  
  257.     // Create the new menu option
  258.     CLTGUITextItemCtrl *pOption = new CLTGUITextItemCtrl;
  259.     if(!pOption->Create(m_pClientDE, dwCommandID, hString, m_pMainMenus->GetSmallFont(), 1, DTRUE, DNULL))
  260.     {
  261.         m_pClientDE->FreeString(hString);
  262.         delete pOption;
  263.         return DNULL;
  264.     }
  265.     m_pClientDE->FreeString(hString);
  266.  
  267.     for(int i = low + 1; i <= high; i++)
  268.     {        
  269.         itoa(i, str, 10);
  270.  
  271.         hString=m_pClientDE->CreateString(str);
  272.         pOption->AddString(hString);
  273.         m_pClientDE->FreeString(hString);
  274.     }
  275.  
  276.     pOption->SetColor(SETRGB(220,190,170), SETRGB(125,30,0));
  277.     pOption->SetSelIndex(index);
  278.     pOption->SetPos(x, y);
  279.  
  280.     return pOption;
  281. }
  282.  
  283. //*************************************************************************
  284.  
  285. CLTGUITextItemCtrl* CMenuCharacter::InitWeaponCtrl(int index, DWORD dwCommandID, int x, int y, DBOOL enable)
  286. {
  287.     // Create the new menu option
  288.     HSTRING hString=m_pClientDE->CreateString("NONE");
  289.  
  290.     CLTGUITextItemCtrl *pOption = new CLTGUITextItemCtrl;
  291.     if(!pOption->Create(m_pClientDE, dwCommandID, hString, m_pMainMenus->GetSmallFont(), 1, DTRUE, DNULL))
  292.     {
  293.         m_pClientDE->FreeString(hString);
  294.         delete pOption;
  295.         return DNULL;
  296.     }
  297.     m_pClientDE->FreeString(hString);
  298.  
  299.     for(int i = 1; i <= WEAP_LASTPLAYERWEAPON; i++)
  300.     {
  301.         hString = m_pClientDE->FormatString(g_WeaponDefaults[i - 1].m_nWeaponNameID);
  302.         pOption->AddString(hString);
  303.         m_pClientDE->FreeString(hString);
  304.     }
  305.  
  306.     pOption->SetColor(SETRGB(220,190,170), SETRGB(125,30,0));
  307.     pOption->SetSelIndex(index);
  308.     pOption->SetPos(x, y);
  309.     pOption->Enable(enable);
  310.  
  311.     return pOption;
  312. }
  313.  
  314. //*************************************************************************
  315.  
  316. CLTGUITextItemCtrl* CMenuCharacter::InitWeaponNumCtrl(int index, DWORD dwCommandID, int x, int y, DBOOL enable)
  317. {
  318.     char    str[5];
  319.  
  320.     HSTRING hString=m_pClientDE->CreateString("0");
  321.  
  322.     // Create the new menu option
  323.     CLTGUITextItemCtrl *pOption = new CLTGUITextItemCtrl;
  324.     if(!pOption->Create(m_pClientDE, dwCommandID, hString, m_pMainMenus->GetSmallFont(), 1, DTRUE, DNULL))
  325.     {
  326.         m_pClientDE->FreeString(hString);
  327.         delete pOption;
  328.         return DNULL;
  329.     }
  330.     m_pClientDE->FreeString(hString);
  331.  
  332.     for(int i = 1; i <= WEAP_LASTPLAYERWEAPON; i++)
  333.     {
  334.         itoa(g_WeaponDefaults[i - 1].m_dwStrengthReq, str, 10);
  335.  
  336.         hString=m_pClientDE->CreateString(str);
  337.         pOption->AddString(hString);
  338.         m_pClientDE->FreeString(hString);
  339.     }
  340.  
  341.     pOption->SetColor(SETRGB(220,190,170), SETRGB(125,30,0));
  342.     pOption->SetSelIndex(index);
  343.     pOption->SetPos(x, y);
  344.     pOption->Enable(enable);
  345.  
  346.     return pOption;
  347. }
  348.  
  349. //*************************************************************************
  350.  
  351. void CMenuCharacter::Render(HSURFACE hDestSurf)
  352. {
  353.     m_pClientDE->DrawSurfaceToSurfaceTransparent(hDestSurf, m_hCharacterPic, DNULL, 78, 119, m_hTransColor);
  354.  
  355.     // Render the list of options
  356.     m_listOption.EnableBoxFormat(m_bBoxFormat);
  357.     m_listOption.Render(hDestSurf);
  358.  
  359.     CheckSelectedLinks();
  360.  
  361.     m_hRightArrow->Render(hDestSurf);
  362.     m_hExtraCtrl->Render(hDestSurf);
  363.     m_hExtraNumCtrl->Render(hDestSurf);
  364.     m_hWeaponsCtrl->Render(hDestSurf);
  365.  
  366.     for(int i = 0; i < 4; i++)
  367.         m_hStats[i]->Render(hDestSurf);
  368.  
  369.     for(i = 0; i < 10; i++)
  370.     {
  371.         m_hWeaponNums[i]->Render(hDestSurf);
  372.         m_hWeapons[i]->Render(hDestSurf);
  373.     }
  374. }
  375.  
  376. //*************************************************************************
  377.  
  378. void CMenuCharacter::CheckSelectedLinks()
  379. {
  380.     int selected = m_listOption.GetSelectedItem();
  381.  
  382.     // Toggle the right arrow with the left arrow
  383.     m_hRightArrow->Select(selected == ARROW_CTRLS);
  384.  
  385.     // Toggle on the Extra Stats stuff with any of the other stats
  386.     if(selected >= MIN_STAT_INDEX && selected <= MAX_STAT_INDEX)
  387.     {
  388.         int    extraIndex = m_hExtraNumCtrl->GetSelIndex();
  389.         m_hExtraCtrl->Select(extraIndex);
  390.         m_hExtraNumCtrl->Select(extraIndex);
  391.  
  392.         m_hStats[0]->Select(selected == MIN_STAT_INDEX);
  393.         m_hStats[1]->Select(selected == MIN_STAT_INDEX + 1);
  394.         m_hStats[2]->Select(selected == MIN_STAT_INDEX + 2);
  395.         m_hStats[3]->Select(selected == MIN_STAT_INDEX + 3);
  396.     }
  397.     else
  398.     {
  399.         m_hExtraCtrl->Select(DFALSE);
  400.         m_hExtraNumCtrl->Select(DFALSE);
  401.  
  402.         m_hStats[0]->Select(DFALSE);
  403.         m_hStats[1]->Select(DFALSE);
  404.         m_hStats[2]->Select(DFALSE);
  405.         m_hStats[3]->Select(DFALSE);
  406.     }
  407.  
  408.     // Toggle the Weapons title with any of the weapon fields
  409.     if(selected >= MIN_WEAPON_INDEX && selected <= MAX_WEAPON_INDEX)
  410.     {
  411.         m_hWeaponsCtrl->Select(DTRUE);
  412.  
  413.         for(int i = 1; i < 10; i++)
  414.         {
  415.             m_hWeapons[i]->Select(selected == MIN_WEAPON_INDEX + i - 1);
  416.             m_hWeaponNums[i]->Select(selected == MIN_WEAPON_INDEX + i - 1);
  417.         }
  418.     }
  419.     else
  420.     {
  421.         m_hWeaponsCtrl->Select(DFALSE);
  422.  
  423.         for(int i = 1; i < 10; i++)
  424.         {
  425.             m_hWeapons[i]->Select(DFALSE);
  426.             m_hWeaponNums[i]->Select(DFALSE);
  427.         }
  428.     }
  429. }
  430.  
  431. //*************************************************************************
  432.  
  433. // This is called to determine whether we should ask the user if they wish to switch
  434. // resolutions back to the previous resolution if it had been changed to 640x480.
  435. void CMenuCharacter::SetResolutionSwitch(DBOOL bAsk, int nOldWidth, int nOldHeight)
  436. {
  437.     m_bSwitchResolutions=bAsk;
  438.     m_nOldScreenWidth=nOldWidth;
  439.     m_nOldScreenHeight=nOldHeight;
  440. }
  441.  
  442. //*************************************************************************
  443. // This is called when the menu gets or loses focus
  444. void CMenuCharacter::OnFocus(DBOOL bFocus)
  445. {
  446.     if (!bFocus)
  447.     {
  448.         if (m_bSwitchResolutions && !m_bGoingToFilesMenu)
  449.         {
  450.             char szMessage[2048];
  451.             sprintf(szMessage, "Would you like to return to your previous screen resolution of %dx%d? (Y/N)", m_nOldScreenWidth, m_nOldScreenHeight);
  452.  
  453.             HSTRING hString=m_pClientDE->CreateString(szMessage);
  454.  
  455.             m_pMainMenus->DoMessageBox(hString, this);
  456.             m_pMainMenus->AddMessageKey(m_pMainMenus->GetYesVKeyCode(), MENU_CMD_CHARACTER_SETUP_SWITCH_RES_BACK);
  457.             m_pMainMenus->AddMessageKey(m_pMainMenus->GetNoVKeyCode(), MENU_CMD_KILL_MESSAGEBOX);            
  458.  
  459.             m_pClientDE->FreeString(hString);
  460.         }
  461.         m_bGoingToFilesMenu=DFALSE;
  462.     }
  463. }
  464.  
  465. //*************************************************************************
  466.  
  467. DDWORD CMenuCharacter::OnCommand(DDWORD dwCommand, DDWORD dwParam1, DDWORD dwParam2)
  468. {    
  469.     switch (dwCommand)
  470.     {
  471.         case MENU_CMD_SAVE_CHARACTER:
  472.         {
  473.             (m_pMainMenus->GetCharacterFiles())->SetAction(MENU_ACTION_SAVE);
  474.             (m_pMainMenus->GetCharacterFiles())->Build();
  475.  
  476.             m_bGoingToFilesMenu=DTRUE;
  477.             m_pMainMenus->SetCurrentMenu(MENU_ID_CHARACTERFILES);
  478.             break;
  479.         }
  480.  
  481.         case MENU_CMD_LOAD_CHARACTER:
  482.         {
  483.             (m_pMainMenus->GetCharacterFiles())->SetAction(MENU_ACTION_LOAD);
  484.             (m_pMainMenus->GetCharacterFiles())->Build();
  485.  
  486.             m_bGoingToFilesMenu=DTRUE;
  487.             m_pMainMenus->SetCurrentMenu(MENU_ID_CHARACTERFILES);
  488.             break;
  489.         }
  490.  
  491.         case MENU_CMD_DELETE_CHARACTER:
  492.         {
  493.             (m_pMainMenus->GetCharacterFiles())->SetAction(MENU_ACTION_DELETE);
  494.             (m_pMainMenus->GetCharacterFiles())->Build();
  495.  
  496.             m_bGoingToFilesMenu=DTRUE;
  497.             m_pMainMenus->SetCurrentMenu(MENU_ID_CHARACTERFILES);
  498.             break;
  499.         }
  500.  
  501.         case MENU_CMD_KILL_MESSAGEBOX:
  502.         {
  503.             m_pMainMenus->KillMessageBox();
  504.             break;
  505.         }
  506.  
  507.         case MENU_CMD_CHARACTER_SETUP_SWITCH_RES_BACK:
  508.         {
  509.             m_pMainMenus->SwitchResolution(m_nOldScreenWidth, m_nOldScreenHeight);
  510.             m_pMainMenus->KillMessageBox();
  511.             break;
  512.         }
  513.     }
  514.     return 0;
  515. }
  516.  
  517. //*************************************************************************
  518.  
  519. DBOOL CMenuCharacter::SaveB2CFile(char *szFile)
  520. {
  521.     FILE    *file = 0;
  522.     char    str1[128];
  523.  
  524.     if(chdir("players") != 0)
  525.         mkdir("players");
  526.     else
  527.         chdir("..");
  528.  
  529.     sprintf(str1, "players\\%s.b2c", szFile);
  530.  
  531.     if(file = fopen(str1, "wb"))
  532.     {
  533.         fwrite(&m_Player, sizeof(B2C), 1, file);
  534.         fclose(file);
  535.     }
  536.     else
  537.         return    DFALSE;
  538.  
  539.     return    DTRUE;
  540. }
  541.  
  542. //*************************************************************************
  543.  
  544. DBOOL CMenuCharacter::LoadB2CFile(char *szFile)
  545. {
  546.     FILE    *file = 0;
  547.     char    str1[128];
  548.  
  549.     sprintf(str1, "players\\%s", szFile);
  550.  
  551.     if(file = fopen(str1, "rb"))
  552.     {
  553.         fread(&m_Player, sizeof(B2C), 1, file);
  554.         fclose(file);
  555.     }
  556.     else
  557.         return    DFALSE;
  558.  
  559.     return    DTRUE;
  560. }
  561.  
  562. //*************************************************************************
  563.  
  564. DBOOL CMenuCharacter::DeleteB2CFile(char *szFile)
  565. {
  566.     char    str1[128];
  567.  
  568.     sprintf(str1, "players\\%s", szFile);
  569.  
  570.     // Don't delete the default files
  571.     if(_mbscmp((const unsigned char*)szFile, (const unsigned char*)"caleb.b2c") == 0)    return DFALSE;
  572.     if(_mbscmp((const unsigned char*)szFile, (const unsigned char*)"ophelia.b2c") == 0)    return DFALSE;
  573.     if(_mbscmp((const unsigned char*)szFile, (const unsigned char*)"ishmael.b2c") == 0)    return DFALSE;
  574.     if(_mbscmp((const unsigned char*)szFile, (const unsigned char*)"gabby.b2c") == 0)    return DFALSE;
  575.     
  576.     if(!remove(str1))
  577.         return    DTRUE;
  578.     else
  579.         return    DFALSE;
  580. }
  581.  
  582. //*************************************************************************
  583.  
  584. void CMenuCharacter::ChangeCharacterPic(int index)
  585. {
  586.     if((index < 0) || (index >= MAX_CHARACTER_INFO))
  587.         return;
  588.  
  589.     char file[128];
  590.     sprintf(file, "interface\\charscreen\\characterpics\\%s", g_CharacterMenuInfo[m_PlayerIndex].szFile);
  591.  
  592. #ifdef _ADDON
  593.     char* sPic = g_CharacterMenuInfo[m_PlayerIndex].szFile;
  594.     if (sPic)
  595.     {
  596.         if (strstr(sPic, "_AO"))
  597.         {
  598.             strcpy(file, sPic);
  599.         }
  600.     }
  601. #endif
  602.  
  603.     if(m_hCharacterPic)
  604.     {
  605.         m_pClientDE->DeleteSurface(m_hCharacterPic);
  606.         m_hCharacterPic = 0;
  607.     }
  608.  
  609.     m_hCharacterPic = m_pClientDE->CreateSurfaceFromBitmap(file);
  610.  
  611.     m_Player.dwCharacter = g_CharacterMenuInfo[m_PlayerIndex].nCharacter;
  612.     m_Player.dwColor = g_CharacterMenuInfo[m_PlayerIndex].nColor;
  613. }
  614.  
  615. //*************************************************************************
  616.  
  617. void CMenuCharacter::UpdateCharacterStruct()
  618. {
  619.     m_Player.dwCharacter    = g_CharacterMenuInfo[m_PlayerIndex].nCharacter;
  620.     m_Player.dwColor        = g_CharacterMenuInfo[m_PlayerIndex].nColor;
  621.     m_Player.dwStrength        = m_hStats[0]->GetSelIndex();
  622.     m_Player.dwResist        = m_hStats[1]->GetSelIndex();
  623.     m_Player.dwSpeed        = m_hStats[2]->GetSelIndex();
  624.     m_Player.dwFocus        = m_hStats[3]->GetSelIndex();
  625.     m_Player.dwWeap1        = m_hWeapons[1]->GetSelIndex();
  626.     m_Player.dwWeap2        = m_hWeapons[2]->GetSelIndex();
  627.     m_Player.dwWeap3        = m_hWeapons[3]->GetSelIndex();
  628.     m_Player.dwWeap4        = m_hWeapons[4]->GetSelIndex();
  629.     m_Player.dwWeap5        = m_hWeapons[5]->GetSelIndex();
  630.     m_Player.dwWeap6        = m_hWeapons[6]->GetSelIndex();
  631.     m_Player.dwWeap7        = m_hWeapons[7]->GetSelIndex();
  632.     m_Player.dwWeap8        = m_hWeapons[8]->GetSelIndex();
  633.     m_Player.dwWeap9        = m_hWeapons[9]->GetSelIndex();
  634. }
  635.  
  636. //*************************************************************************
  637.  
  638. void CMenuCharacter::SetPlayerIndexFromStruct()
  639. {
  640.     for(int i = 0; i < MAX_CHARACTER_INFO; i++)
  641.     {
  642.         if(m_Player.dwCharacter == g_CharacterMenuInfo[i].nCharacter)
  643.             if(m_Player.dwColor == g_CharacterMenuInfo[i].nColor)
  644.                 break;
  645.     }
  646.  
  647.     m_PlayerIndex = i;
  648. }
  649.  
  650. //*************************************************************************
  651.  
  652. void CMenuCharacter::UpdateScreenFromStruct()
  653. {
  654.     int total = m_Player.dwStrength + m_Player.dwSpeed + m_Player.dwResist + m_Player.dwFocus;
  655.     int i;
  656.     DBOOL nuke = DFALSE;
  657.  
  658.     // Check the total attributes
  659.     if(total > MAX_ATTRIBUTES)        nuke = DTRUE;
  660.  
  661.     // Check the individual attributes
  662.     if((m_Player.dwStrength < 0) || (m_Player.dwStrength > MAX_ATTRIBUTE))    nuke = DTRUE;
  663.     if((m_Player.dwSpeed < 0) || (m_Player.dwSpeed > MAX_ATTRIBUTE))        nuke = DTRUE;
  664.     if((m_Player.dwResist < 0) || (m_Player.dwResist > MAX_ATTRIBUTE))        nuke = DTRUE;
  665.     if((m_Player.dwFocus < 0) || (m_Player.dwFocus > MAX_ATTRIBUTE))        nuke = DTRUE;
  666.  
  667.     if(nuke)
  668.     {
  669.         // If the attributes in the file are too high (someone trys to cheat) then nuke 'em
  670.         m_PlayerIndex = 0;
  671.  
  672.         for(i = 0; i < 4; i++)
  673.             m_hStats[i]->SetSelIndex(DEFAULT_ATTRIBUTE);
  674.  
  675.         m_hExtraNumCtrl->SetSelIndex(0);
  676.     }
  677.     else
  678.     {
  679.         // Otherwise just set them to what's in the file
  680.         SetPlayerIndexFromStruct();
  681.  
  682.         m_hStats[0]->SetSelIndex(m_Player.dwStrength);
  683.         m_hStats[1]->SetSelIndex(m_Player.dwResist);
  684.         m_hStats[2]->SetSelIndex(m_Player.dwSpeed);
  685.         m_hStats[3]->SetSelIndex(m_Player.dwFocus);
  686.         m_hExtraNumCtrl->SetSelIndex(MAX_ATTRIBUTES - total);
  687.     }
  688.  
  689.     // Get a pointer to the first weapon for easier loop checkin'
  690.     DDWORD    *weapon = &(m_Player.dwWeap1);
  691.  
  692.     for(i = 1; i < 10; i++)
  693.     {
  694.         DDWORD    weap = weapon[i - 1];
  695.  
  696.         if((weap > 0) && (weap <= WEAP_LASTPLAYERWEAPON))
  697.         {
  698.             m_hWeapons[i]->SetSelIndex(weap);
  699.             m_hWeaponNums[i]->SetSelIndex(weap);
  700.         }
  701.         else
  702.         {
  703.             m_hWeapons[i]->SetSelIndex(0);
  704.             m_hWeaponNums[i]->SetSelIndex(0);
  705.             weapon[i - 1] = 0;
  706.         }
  707.     }
  708.  
  709.     ChangeCharacterPic(m_PlayerIndex);
  710. }
  711.  
  712. //*************************************************************************
  713.  
  714. DBOOL CMenuCharacter::IsWeaponADupe(int index)
  715. {
  716.     for(int i = 0; i < 10; i++)
  717.     {
  718.         if(i != index)
  719.         {
  720.             int    index1 = m_hWeapons[index]->GetSelIndex();
  721.             int    index2 = m_hWeapons[i]->GetSelIndex();
  722.             if(index1 == index2) return DTRUE;
  723.         }
  724.     }
  725.  
  726.     return    DFALSE;
  727. }
  728.  
  729. //*************************************************************************
  730.  
  731. void CMenuCharacter::OnLeft()
  732. {
  733.     int selected = m_listOption.GetSelectedItem();
  734.  
  735.     // Handle left on arrows
  736.     if(selected == ARROW_CTRLS)
  737.     {
  738.         m_PlayerIndex--;
  739.  
  740.         if(m_PlayerIndex < 0)
  741.             m_PlayerIndex = MAX_CHARACTER_INFO - 1;
  742.  
  743.         ChangeCharacterPic(m_PlayerIndex);
  744.     }
  745.  
  746.     // Handle left on stats
  747.     if(selected >= MIN_STAT_INDEX && selected <= MAX_STAT_INDEX)
  748.     {
  749.         int    index1 = m_hStats[selected - MIN_STAT_INDEX]->GetSelIndex();
  750.         int index2 = m_hExtraNumCtrl->GetSelIndex();
  751.  
  752.         if(index1 > 1)
  753.         {
  754.             m_hStats[selected - MIN_STAT_INDEX]->OnLeft();
  755.             index2++;
  756.             m_hExtraNumCtrl->SetSelIndex(index2);
  757.         }
  758.     }
  759.  
  760.     // Handle left on weapons
  761.     if(selected >= MIN_WEAPON_INDEX && selected <= MAX_WEAPON_INDEX)
  762.     {
  763.         int value = selected - MIN_WEAPON_INDEX + 1;
  764.         int    index1 = m_hWeapons[value]->GetSelIndex();
  765.  
  766.         // Find the next available weapon to the left or set to NONE
  767.         if(index1 > 0)
  768.         {
  769.             while(1)
  770.             {
  771.                 m_hWeapons[value]->OnLeft();
  772.                 m_hWeaponNums[value]->OnLeft();
  773.                 index1--;
  774.  
  775.                 if((index1 == 0) || (!IsWeaponADupe(value)))
  776.                     break;
  777.             }
  778.         }
  779.     }
  780.  
  781.     UpdateCharacterStruct();
  782. }
  783.  
  784. //*************************************************************************
  785.  
  786. void CMenuCharacter::OnRight()
  787. {
  788.     int selected = m_listOption.GetSelectedItem();
  789.  
  790.     // Handle left on arrows
  791.     if(selected == ARROW_CTRLS)
  792.     {
  793.         m_PlayerIndex++;
  794.  
  795.         if(m_PlayerIndex >= MAX_CHARACTER_INFO)
  796.             m_PlayerIndex = 0;
  797.  
  798.         ChangeCharacterPic(m_PlayerIndex);
  799.     }
  800.  
  801.     // Toggle on the Extra Stats stuff with any of the other stats
  802.     if(selected >= MIN_STAT_INDEX && selected <= MAX_STAT_INDEX)
  803.     {
  804.         int    index1 = m_hStats[selected - MIN_STAT_INDEX]->GetSelIndex();
  805.         int index2 = m_hExtraNumCtrl->GetSelIndex();
  806.  
  807.         if((index1 < MAX_ATTRIBUTE) && (index2 > 0))
  808.         {
  809.             m_hStats[selected - MIN_STAT_INDEX]->OnRight();
  810.             index2--;
  811.             m_hExtraNumCtrl->SetSelIndex(index2);
  812.         }
  813.     }
  814.  
  815.     // Toggle the Weapons title with any of the weapon fields
  816.     if(selected >= MIN_WEAPON_INDEX && selected <= MAX_WEAPON_INDEX)
  817.     {
  818.         int value = selected - MIN_WEAPON_INDEX + 1;
  819.         int    index1 = m_hWeapons[value]->GetSelIndex();
  820.         int index2 = index1;
  821.         DBOOL resetWeap = DFALSE;
  822.  
  823.         // Find the next available weapon to the left or set to NONE
  824.         if(index2 < WEAP_LASTPLAYERWEAPON)
  825.         {
  826.             while(1)
  827.             {
  828.                 m_hWeapons[value]->OnRight();
  829.                 m_hWeaponNums[value]->OnRight();
  830.                 index2++;
  831.  
  832.                 if(!IsWeaponADupe(value))
  833.                     break;
  834.                 else if((index2 == WEAP_LASTPLAYERWEAPON) && (IsWeaponADupe(value)))
  835.                 {
  836.                     resetWeap = DTRUE;
  837.                     break;
  838.                 }
  839.             }
  840.         }
  841.  
  842.         // If there wasn't a valid weapon to the right... then reset it to what it was
  843.         if(resetWeap)
  844.         {
  845.             m_hWeapons[value]->SetSelIndex(index1);
  846.             m_hWeaponNums[value]->SetSelIndex(index1);
  847.         }
  848.     }
  849.  
  850.     UpdateCharacterStruct();
  851. }